package com.video.netty.InChannelHandler;

import com.alibaba.fastjson.JSONObject;
import com.video.commons.runtimelog.RequestIdThreadLocal;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.annotation.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@ChannelHandler.Sharable
public abstract class BaseChannelHandler extends SimpleChannelInboundHandler<JSONObject> {

    //创建一个长度为10的线程池
    private ExecutorService executors = Executors.newFixedThreadPool(10);

    /**
     * 自定义注解
     */
    @Documented
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Order(200)
    @Component
    protected  @interface MsgHandler{

    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, JSONObject json) {

        //获得当前请求的url
        String requestId = RequestIdThreadLocal.getId();

        //将文本转换成json字符串
        String id = json.getString("id");
        if(msgId() != null && msgId().equals(id)){
            //全部交给线程池处理
            executors.submit(() -> {
                try {
                    //使的只线程的请求id和主线程保持一致
                    RequestIdThreadLocal.putId(requestId);

                    //去掉id属性
                    json.remove("id");

                    //如果id相等，就由当前Handler处理
                    msgHandler(json);
                } catch (Exception e) {
                    //如果有异常，就调用异常处理
                    exceptionHandler(json, e);
                } finally{
                    RequestIdThreadLocal.clear();
                }
            });
        } else {
            //如果不相等，则继续往后传递
            ctx.fireChannelRead(json);
        }
    }

    /**
     * 需要处理的消息id字符串
     * @return
     */
    protected abstract String msgId();

    protected abstract void msgHandler(JSONObject json) throws Exception;

    protected void exceptionHandler(JSONObject json, Exception e){

    }
}
